package io.renren.modules.medical.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.exception.MedicalException;
import io.renren.common.result.ResultCodeEnum;
import io.renren.common.utils.*;
import io.renren.modules.medical.dao.HealthEducationDao;
import io.renren.modules.medical.entity.DoctorInfoEntity;
import io.renren.modules.medical.entity.EducationContentEntity;
import io.renren.modules.medical.entity.HealthEducationEntity;
import io.renren.modules.medical.entity.IllSubEntity;
import io.renren.modules.medical.service.DoctorInfoService;
import io.renren.modules.medical.service.EducationContentService;
import io.renren.modules.medical.service.HealthEducationService;
import io.renren.modules.medical.service.IllSubService;
import io.renren.modules.medical.vo.medicalVo.HealthEducationListVo;
import io.renren.modules.medical.vo.medicalVo.HealthEducationSaveVo;
import io.renren.modules.medical.vo.medicalVo.StatusVo;
import io.renren.modules.medical.vo.weixinVo.ApiHealthDetailVo;
import io.renren.modules.medical.vo.weixinVo.ApiHealthEducationVo;
import io.renren.modules.sys.service.SysUserRoleService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpStatus;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.transaction.annotation.Transactional;

@RequiredArgsConstructor
@Service("healthEducationService")
public class HealthEducationServiceImpl extends ServiceImpl<HealthEducationDao, HealthEducationEntity> implements HealthEducationService {

    private final IllSubService illSubService;

    private final DoctorInfoService doctorInfoService;

    private final EducationContentService educationContentService;

    private final SysUserRoleService sysUserRoleService;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        // 先获取基础封装信息
        IPage<HealthEducationEntity> page = getBaseIPage(params);

        // 获取到原先的数据
        List<HealthEducationEntity> records = page.getRecords();
        // 遍历封装
        List<HealthEducationListVo> healthEducationListVos = records.stream().map(item -> {
            HealthEducationListVo healthEducationListVo = new HealthEducationListVo();
            BeanUtils.copyProperties(item, healthEducationListVo);
            if (item.getSubId() != null){
                IllSubEntity illSubEntity = illSubService.getById(item.getSubId());
                healthEducationListVo.setSubTitle(illSubEntity.getTitle() != null ? illSubEntity.getTitle() : "");
            }

            if (item.getDoctorId() != null){
                DoctorInfoEntity doctorInfoEntity = doctorInfoService.getById(item.getDoctorId());
                healthEducationListVo.setDoctorName(doctorInfoEntity.getName() != null ? doctorInfoEntity.getName() : "");
            }
            return healthEducationListVo;
        }).collect(Collectors.toList());

        // 返回page对象
        Page<HealthEducationListVo> healthEducationVoPage = new Page<>();
        BeanUtils.copyProperties(page, healthEducationVoPage);
        healthEducationVoPage.setRecords(healthEducationListVos);
        return new PageUtils(healthEducationVoPage);
    }


    @Override
    public void updateStatus(StatusVo statusVo) {
        HealthEducationEntity healthEducationEntity = new HealthEducationEntity();
        BeanUtils.copyProperties(statusVo, healthEducationEntity);
        DoctorInfoEntity doctorInfo = DoctorInfoUtils.getDoctorInfo(doctorInfoService);
        if (statusVo.getStatus() == Constant.AuditStatus.REJECT.getValue() || statusVo.getStatus() == Constant.AuditStatus.USING.getValue()) {
            HealthEducationEntity educationEntity = this.getById(statusVo.getId());
            if (educationEntity.getStatus() == Constant.AuditStatus.STOPING.getValue()){
                    throw new MedicalException(ResultCodeEnum.CANT_UPDATE_STATUS.getCode(), "无法审核停用中的健康教育");
            }
            // 如果是审核通过或不过的话就添加上审核id
            healthEducationEntity.setAuditorId(doctorInfo.getId());
        }
        this.updateById(healthEducationEntity);
    }

    @Transactional
    @Override
    public void saveHealthEducation(HealthEducationSaveVo healthEducation) {
        // 判断添加的时间和现在时间
        Date publishTime = healthEducation.getPublishTime();
        if (publishTime.getTime() < System.currentTimeMillis()){
            throw new MedicalException(ResultCodeEnum.PUBLISH_TIME_ERROR.getCode(), "教育发布时间不能小于当前时间");
        }

        // 先保存healthEducation对象
        HealthEducationEntity educationEntity = new HealthEducationEntity();
        BeanUtils.copyProperties(healthEducation, educationEntity);
        // System.out.println(educationEntity);
        DoctorInfoEntity doctorInfoEntity = DoctorInfoUtils.getDoctorInfo(doctorInfoService);
        educationEntity.setDoctorId(doctorInfoEntity.getId());
        educationEntity.setSubId(doctorInfoEntity.getDepId());
        this.save(educationEntity);

        // 再保存EducationContent对象
        EducationContentEntity educationContentEntity = new EducationContentEntity();
        educationContentEntity.setContent(healthEducation.getContent());
        educationContentEntity.setDoctorId(doctorInfoEntity.getId());
        educationContentService.save(educationContentEntity);
        // 添加上contentId
        educationEntity.setContentId(educationContentEntity.getId());
        this.updateById(educationEntity);
    }


    @Override
    public Map<String, Object> getInfoById(Long id) {
        HealthEducationEntity educationEntity = this.getById(id);
        HashMap<String, Object> resultMap = new HashMap<>();
        resultMap.put("title", educationEntity.getTitle());
        resultMap.put("defaultPic", educationEntity.getDefaultPic());
        resultMap.put("publishTime", educationEntity.getPublishTime());
        EducationContentEntity contentEntity = educationContentService.getById(educationEntity.getContentId() == null ? 0 : educationEntity.getContentId());
        if (contentEntity != null){
            resultMap.put("content", contentEntity.getContent());
        }else {
            resultMap.put("content", "");
        }
        return resultMap;
    }

    @Override
    public void updateHealthEducation(HealthEducationSaveVo healthEducation) {
        // 获取到发布时间
        HealthEducationEntity educationEntity = new HealthEducationEntity();
        BeanUtils.copyProperties(healthEducation, educationEntity);
        this.updateById(educationEntity);
        HealthEducationEntity healthEducationEntity = this.getById(educationEntity.getId());
        if (healthEducationEntity.getContentId() == null){
            // 没有contentId增加内容
            EducationContentEntity educationContentEntity = new EducationContentEntity();
            educationContentEntity.setContent(healthEducation.getContent());
            educationContentEntity.setDoctorId(DoctorInfoUtils.getDoctorInfo(doctorInfoService).getId());
            educationContentService.save(educationContentEntity);
            healthEducationEntity.setContentId(educationContentEntity.getId());
            this.updateById(healthEducationEntity);
            return;
        }

        // 有contentId就修改
        EducationContentEntity educationContentEntity = educationContentService.getById(healthEducationEntity.getContentId());
        educationContentEntity.setContent(healthEducation.getContent());
        educationContentService.updateById(educationContentEntity);

    }

    @Transactional
    @Override
    public void removeHealthEducation(List<Long> asList) {
        LambdaQueryWrapper<HealthEducationEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(asList != null && asList.size() > 0, HealthEducationEntity::getId, asList);
        List<HealthEducationEntity> list = this.list(queryWrapper);
        List<Long> contentIds = list.stream().map(HealthEducationEntity::getContentId
        ).collect(Collectors.toList());
        this.removeByIds(asList);
        educationContentService.removeByIds(contentIds);
    }

    /**
     * 微信小程序端获取健康教育分页的方法
     */
    @Override
    public PageUtils getPage(Map<String, Object> params) {
        IPage<HealthEducationEntity> page = getBasePageByParams(params);
        List<HealthEducationEntity> records = page.getRecords();
        List<ApiHealthEducationVo> apiHealthEducationVos = records.stream()
                .filter(item -> item.getStatus() == 1 && item.getPublishTime().getTime() < System.currentTimeMillis())
                .map(item -> {
                    ApiHealthEducationVo educationVo = new ApiHealthEducationVo();
                    BeanUtils.copyProperties(item, educationVo);
                    educationVo.setPublishTime(DateUtils.format(item.getPublishTime()));
                    return educationVo;

                }).collect(Collectors.toList());
        Page<ApiHealthEducationVo> apiHealthEducationVoPage = new Page<>();
        BeanUtils.copyProperties(page, apiHealthEducationVoPage);
        apiHealthEducationVoPage.setRecords(apiHealthEducationVos);
        return new PageUtils(apiHealthEducationVoPage);
    }

    /**
     * 获取详细信息
     */
    @Override
    public ApiHealthDetailVo getDetailById(Long id) {
        HealthEducationEntity educationEntity = this.getById(id);
        if(educationEntity != null){
            EducationContentEntity contentEntity = educationContentService.getById(educationEntity.getContentId());
            ApiHealthDetailVo detailVo = new ApiHealthDetailVo();
            detailVo.setPublishTime(DateUtils.format(educationEntity.getPublishTime(), DateUtils.DATE_TIME_PATTERN));
            BeanUtils.copyProperties(educationEntity, detailVo);
            detailVo.setContent(contentEntity != null ? contentEntity.getContent() : "");
            DoctorInfoEntity doctorInfoEntity = doctorInfoService.getById(educationEntity.getDoctorId());
            detailVo.setDoctorName(doctorInfoEntity.getName());
            return detailVo;
        }

        return new ApiHealthDetailVo();
    }

    /**
     * 微信端获取基础封装信息
     */
    private IPage<HealthEducationEntity> getBasePageByParams(Map<String, Object> params) {
        // 根据发布的id 发布的题目来匹配
        LambdaQueryWrapper<HealthEducationEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 设置基础构造条件
        String subId = (String) params.get("subId");
        // 根据参数限制得到数据集合
        if(StringUtils.isNotEmpty(subId)) {
            queryWrapper.eq(HealthEducationEntity::getSubId, subId);
        }else {
            return new Page<>();
        }

        // 根据发布时间排序
        queryWrapper.orderByDesc(HealthEducationEntity::getPublishTime);
        return this.page(
                new Query<HealthEducationEntity>().getPage(params),
                queryWrapper
        );
    }

    /**
     * 管理端获取基础封装信息
     */
    private IPage<HealthEducationEntity> getBaseIPage(Map<String, Object> params) {
        // 根据发布的id 发布的题目来匹配
        LambdaQueryWrapper<HealthEducationEntity> queryWrapper = new LambdaQueryWrapper<>();
        // 设置基础构造条件
        String key = (String) params.get("key");
        // 根据参数限制得到数据集合
        if(StringUtils.isNotEmpty(key)) {
            queryWrapper.and(obj -> obj.eq(StringUtils.isNotEmpty(key), HealthEducationEntity::getId, key)
                    .or().like(StringUtils.isNotEmpty(key), HealthEducationEntity::getTitle, key));
        }

        // 判断当前用户是医生还是管理员或者审核
        List<Long> roles = DoctorInfoUtils.getRole(sysUserRoleService);

        if(!roles.contains(Constant.SysRole.ADMIN.getValue()) && !roles.contains(Constant.SysRole.AUDITOR.getValue())){
            if (roles.contains(Constant.SysRole.DOCTOR.getValue())){
                // 医生就只访问当前病情分类下的所有健康教育
                DoctorInfoEntity doctorInfo = DoctorInfoUtils.getDoctorInfo(doctorInfoService);
                queryWrapper.eq(HealthEducationEntity::getDoctorId, doctorInfo.getId());
            }else {
                throw new MedicalException(HttpStatus.SC_FORBIDDEN, "用户无权访问健康教育列表");
            }
        }

        // 根据发布时间排序
        queryWrapper.orderByDesc(HealthEducationEntity::getPublishTime);
        return this.page(
                new Query<HealthEducationEntity>().getPage(params),
                queryWrapper
        );
    }
}